package com.itheima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hankcs.algorithm.AhoCorasickDoubleArrayTrie;
import com.itheima.admin.mapper.AdChannelMapper;
import com.itheima.admin.mapper.AdSensitiveMapper;
import com.itheima.admin.pojo.AdChannel;
import com.itheima.admin.pojo.AdSensitive;
import com.itheima.admin.service.WemediaNewsAutoScanService;
import com.itheima.article.dto.ArticleInfoDto;
import com.itheima.article.feign.ApArticleFeign;
import com.itheima.article.pojo.ApArticle;
import com.itheima.article.pojo.ApArticleConfig;
import com.itheima.article.pojo.ApArticleContent;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.util.ali.AliGreenScanner;
import com.itheima.common.vo.ResultVo;
import com.itheima.dfs.feign.DfsFeign;
import com.itheima.wemedia.dto.WmNewsContentNodeDto;
import com.itheima.wemedia.feign.WmNewsFeign;
import com.itheima.wemedia.pojo.WmNews;
import com.itheima.wemedia.vo.WmNewsVo;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.swing.SwingUtilities2;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {
    @Autowired
    private WmNewsFeign wmNewsFeign;
    @Autowired
    private AdSensitiveMapper adSensitiveMapper;
    @Autowired
    private AliGreenScanner aliGreenScanner;
    @Autowired
    private DfsFeign dfsFeign;
    @Autowired
    private AdChannelMapper adChannelMapper;
    @Autowired
    private ApArticleFeign apArticleFeign;

    @Override
    public void autoScanWemediaNewsById(Integer wmNewsId, String uuid) {
        //通过文章id查询
        ResultVo<WmNews> wmNewsResultVo = wmNewsFeign.getWmNewsById(wmNewsId);
        //获取WmNews文章
        WmNews wmNews = wmNewsResultVo.getData();
        log.info("获取文章成功");
        //判断远程调用是否成功
        if (!wmNewsResultVo.isSuccess()){
            log.error("【出错】文章自动审核：uuid={},id={} 远程调用查询文章失败",uuid,wmNewsId);
            return;
        }
        if (null==wmNews){
            log.error("【出错】文章自动审核：uuid={},id={} 远程调用查询不到文章",uuid,wmNewsId);
            return;
        }
        //判断是否是查询状态
        if(wmNews.getStatus() != BusinessConstants.WmNewsConstants.STATUS_SUBMIT){
            log.error("【出错】文章自动审核：uuid={},id={},status={} 文章状态不正确",uuid,wmNewsId,wmNews.getStatus());
            return;
        }
        //提取文本  需要提取的是内容文本和标题
        //如何提取文本，文本内容的格式是集合，所以需要遍历type=text，获取value
        //创建用来解析文本内容的方法

        String text = getTextFromWmNews(wmNews);
        WmNews updatePojo = new WmNews();
        updatePojo.setId(Long.valueOf(wmNewsId));
        //根据敏感词去审核文本，，检测敏感词
        if (sensitiveWordsCheck(text)){
            //有敏感词,审核不通过，更新状态
            updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_FAIL);
            updatePojo.setReason("文章内容包含敏感词");

        }else {
            //反垃圾
            //文本反垃圾
            try {
                Map<String, String> ScanResult = aliGreenScanner.greenTextScan(text);
                String suggestion = ScanResult.get("suggestion");
                if (BusinessConstants.ScanConstants.PASS.equals(suggestion)){
                    //图片反垃圾
                    //提取 文章中的图片 调用dfs服务 批量下载
                    List<String> imageList = getImaesFromWmnews(wmNews);
                    log.info("图片列表=========,{}",imageList);
                    if (CollectionUtils.isNotEmpty(imageList)){
                        ResultVo<List<byte[]>> downloadResult = dfsFeign.download(imageList);
                        //
                        if (!downloadResult.isSuccess()){
                            log.error("【出错】文章自动审核：uuid={},id={} 远程调用下载文章图片失败",uuid,wmNewsId);
                            return;
                        }
                        List<byte[]> imageDataList = downloadResult.getData();
                        //图片反垃圾
                        ScanResult = aliGreenScanner.imageScan(imageDataList);
                    }
                }
                //解析结果
                switch (suggestion){
                    case BusinessConstants.ScanConstants.BLOCK:
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_FAIL);
                        updatePojo.setReason("内容违反相关规定");
                        break;
                    case BusinessConstants.ScanConstants.REVIEW:
                        //需要人工审核
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_MANUAL);
                        log.debug("转人工审核");
                        break;
                    case BusinessConstants.ScanConstants.PASS:
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_PASS);
                        log.debug("审核通过");
                        break;
                    default: log.error("【出错】文章自动审核：uuid={},id={} 调用aliyun安全内容审核结果不正常",uuid,wmNewsId);return;
                }
            }catch (Exception e){
                log.error("【出错】文章自动审核：uuid={},id={} 调用阿里反垃圾失败",uuid,wmNewsId);
                return;
            }
        }
        wmNewsFeign.update(updatePojo);


    }

    /**
     * 同步article文章微服务
     * @param wmNewsVo
     * @return
     */
    @Override
    @Transactional
    public boolean syncArticleInfo(WmNewsVo wmNewsVo) {
        //同步文章
        //创建文章信息article对象,内容，config，远程调用添加文章信息
        ArticleInfoDto articleInfoDto = new ArticleInfoDto();
        //构建文章信息
        ApArticle apArticle = buildApArticle(wmNewsVo);
        //构建dto,更好进行远程调用
        articleInfoDto.setApArticle(apArticle);
//        构建文章内容
        ApArticleContent apArticleContent = new ApArticleContent();
        //文章id 在添加之后再查询文章id，再去设置，就不再这里设置
//        apArticleContent.setArticleId(Long.valueOf(wmNewsVo.getArticleId()));
        apArticleContent.setContent(wmNewsVo.getContent());
        articleInfoDto.setApArticleContent(apArticleContent);
        //构建config
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setIsDown(0);// 初始化为非下架
        apArticleConfig.setIsDelete(0);// 0：没被删除
        apArticleConfig.setIsForward(1);//是否转发
        apArticleConfig.setIsComment(1);//是否可以评论
        articleInfoDto.setApArticleConfig(apArticleConfig);

        //5. 自媒体用户
        articleInfoDto.setWmUserId(wmNewsVo.getUserId());
        // app用户id 作者
        articleInfoDto.setApUserId(wmNewsVo.getApUserId());
        // 自媒体文章id(更新状态)
        articleInfoDto.setWmNewsId(Long.valueOf(wmNewsVo.getId()));
        //6. 远程调用文章微服务保存文章信息
        ResultVo resultVo = apArticleFeign.saveArticleInfo(articleInfoDto);
        //7. 解析返回结果
        return resultVo.isSuccess();
    }



    /**
     * 构建文章信息
     * @param wmNewsVo
     * @return
     */
    private ApArticle buildApArticle(WmNewsVo wmNewsVo) {
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(wmNewsVo,apArticle);
        apArticle.setId(null);
        apArticle.setAuthorId(wmNewsVo.getApUserId());
        AdChannel adChannel = adChannelMapper.selectById(wmNewsVo.getChannelId());
        apArticle.setChannelName(adChannel.getName());
        // 布局
        apArticle.setLayout(wmNewsVo.getType());
        apArticle.setFlag(0);//普通文章
        apArticle.setLikes(0);
        apArticle.setCollection(0);
        apArticle.setComment(0);
        apArticle.setViews(0);
        apArticle.setProvinceId(0);
        apArticle.setCityId(0);
        apArticle.setCountyId(0);
        apArticle.setSyncStatus(0);//0:未同步给es
        apArticle.setOrigin(1);//1:自媒体，2：爬虫
        return apArticle;
    }

    private List<String> getImaesFromWmnews(WmNews wmNews) {
        String content = wmNews.getContent();
        //细节,将原来的WmNewsContentNodeDto放在wemediaApi中，公用
        //JSON.parseArray:将类似于json的字符串转化为集合
        List<WmNewsContentNodeDto> contentNodeList = JSON.parseArray(content, WmNewsContentNodeDto.class);
        List<String> imageList = contentNodeList.stream().filter(node->"image".equals(node.getType())).map(WmNewsContentNodeDto::getValue).collect(Collectors.toList());
        //添加封面，多张封面同样是以逗号分割
        String images = wmNews.getImages();
        if (StringUtils.isNotEmpty(images)){
            String[] split = images.split(",");
            Collections.addAll(imageList,split);
        }

        return imageList;
    }

    /**
     * 敏感词检测
     * @param text
     * @return
     */
    private boolean sensitiveWordsCheck(String text) {
        //查询数据库的敏感词
        QueryWrapper<AdSensitive> query = Wrappers.<AdSensitive>query().select("sensitives");

        List<AdSensitive> sensitiveList = adSensitiveMapper.selectList(query);
        if (CollectionUtils.isNotEmpty(sensitiveList)){
            //没有敏感词
            return false;
        }
        Map<String, String> map = sensitiveList.stream().collect(Collectors.toMap(AdSensitive::getSensitives, AdSensitive::getSensitives));
        //构建字典
        AhoCorasickDoubleArrayTrie<String> trie = new AhoCorasickDoubleArrayTrie<>();
        trie.build(map);
        AhoCorasickDoubleArrayTrie.Hit<String> first = trie.findFirst(text);

        return first!=null;


    }


    private String getTextFromWmNews(WmNews wmNews) {
        String content = wmNews.getContent();
        //细节,将原来的WmNewsContentNodeDto放在wemediaApi中，公用
        //JSON.parseArray:将类似于json的字符串转化为集合
        List<WmNewsContentNodeDto> contentNodeList = JSON.parseArray(content, WmNewsContentNodeDto.class);
        List<String> textList = contentNodeList.stream().filter(node->"text".equals(node.getType())).map(WmNewsContentNodeDto::getValue).collect(Collectors.toList());

        textList.add(wmNews.getTitle());

        return String.join(",",textList);
    }
}
